/*
GanttProject is an opensource project management tool. License: GPL3
Copyright (C) 2010 Dmitry Barashev

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package net.sourceforge.ganttproject.chart.mouse;

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.util.Date;

import net.sourceforge.ganttproject.GPLogger;
import net.sourceforge.ganttproject.chart.TaskInteractionHintRenderer;
import net.sourceforge.ganttproject.chart.mouse.MouseInteraction.TimelineFacade;
import net.sourceforge.ganttproject.gui.UIFacade;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskMutator;
import net.sourceforge.ganttproject.task.algorithm.RecalculateTaskScheduleAlgorithm;
import net.sourceforge.ganttproject.task.dependency.TaskDependencyException;

public abstract class ChangeTaskBoundaryInteraction extends MouseInteractionBase {
    private TaskInteractionHintRenderer myLastNotes;

    private final Task myTask;

    private final UIFacade myUiFacade;

    private final RecalculateTaskScheduleAlgorithm myTaskScheduleAlgorithm;

    protected ChangeTaskBoundaryInteraction(
            Date startDate, Task task, TimelineFacade chartDateGrid,
            UIFacade uiFacade, RecalculateTaskScheduleAlgorithm taskScheduleAlgorithm) {
        super(startDate, chartDateGrid);
        myTask = task;
        myUiFacade = uiFacade;
        myTaskScheduleAlgorithm = taskScheduleAlgorithm;
    }

    protected void updateTooltip(MouseEvent e) {
        if (myLastNotes == null) {
            myLastNotes = new TaskInteractionHintRenderer("", e.getX(), e.getY());
        }
        myLastNotes.setString(getNotesText());
        myLastNotes.setX(e.getX());
    }

    protected Task getTask() {
        return myTask;
    }

    public void finish(final TaskMutator mutator) {
        mutator.setIsolationLevel(TaskMutator.READ_UNCOMMITED);
        myUiFacade.getUndoManager().undoableEdit("Task boundary changed",
                new Runnable() {
                    @Override
                    public void run() {
                        doFinish(mutator);
                    }
                });
    }

    private void doFinish(TaskMutator mutator) {
        mutator.commit();
        myLastNotes = null;
        try {
            myTaskScheduleAlgorithm.run();
        } catch (TaskDependencyException e) {
            if (!GPLogger.log(e)) {
                e.printStackTrace(System.err);
            }
            myUiFacade.showErrorDialog(e);
        }
        myUiFacade.getActiveChart().reset();
    }

    @Override
    public void paint(Graphics g) {
        if (myLastNotes != null) {
            myLastNotes.paint(g);
        }
    }

    protected abstract String getNotesText();
}